<script>
import {h, reactive, ref, toRaw, toRefs} from 'vue';
import {Table} from 'ant-design-vue';

export default {
  name: 'SagTable',
  props: Object.assign({}, Table.props, {
    rowKey: { type: [String, Function], default: 'key' },
    data: { type: Function, required: true },
    pageNum: { type: Number, default: 1 },
    pageSize: { type: Number, default: 10 },
    showSizeChanger: { type: Boolean, default: true }, // 显示每页条数选项
    size: { type: String, default: 'small' },
    class: { type: Array },
    columns: { type: Array },
    rowSelection: { type: Object, default: null },
    showPagination: { type: [String, Boolean], default: true }, // auto
    bordered: {type: Boolean, default: true},
    pagination:{type: Object,
      default: ()=>({
          showTotal:(total, range)=>{return `共${total}条`;}
      })
    }
  }),
  emits: ['expand'],
  data() {
    return {
      localLoading: false,
      localDataSource: [],
      localPagination: Object.assign({
        pageSizeOptions:['10', '20', '50', '100', '1000']
      }, this.pagination),
    };
  },
  watch: {
    'localPagination.current'(val) {

    },
    pageNum(val) {
      Object.assign(this.localPagination, {
        current: val,
      });
    },
    pageSize(val) {
      Object.assign(this.localPagination, {
        pageSize: val,
      });
    },
    showSizeChanger(val) {
      Object.assign(this.localPagination, {
        showSizeChanger: val,
      });
    },
  },
  created() {
    const localPageNum = this.pageNum;
    this.localPagination =
      (['auto', true].includes(this.showPagination) &&
        Object.assign({}, this.localPagination, {
          current: localPageNum,
          pageSize: this.pageSize,
          showSizeChanger: this.showSizeChanger,
        })) ||
      false;
    this.loadData(null, {}, null);
  },
  computed:{
    hasRowNo(){
      return this.columns.some(x=>x.dataIndex === 'rowNo');
    }
  },
  methods: {
    clear(){
      this.localDataSource = [];
    },
    /**
     * 表格重新加载方法
     *
     * @param bool 如果参数为 true, 则强制刷新到第一页
     */
    refresh(bool = false) {
      bool &&
        (this.localPagination = Object.assign(
          {},
          {
            current: 1,
            pageSize: this.pageSize,
          }
        ));
      this.loadData(null, {}, null);
    },
    /**
     * 加载数据方法
     * @param {Object} pagination 分页选项器
     * @param {Object} filters 过滤条件
     * @param {Object} sorter 排序条件
     */
    loadData(pagination, filters, sorter) {
      this.localLoading = true;

      const pageNo = (pagination && pagination.current) ||
        (this.showPagination && this.localPagination.current) ||
        this.pageNum;
      const pageSize = (pagination && pagination.pageSize) ||
        (this.showPagination && this.localPagination.pageSize) ||
        this.pageSize;

      const parameter = Object.assign(
        {
          pageNo,
          pageSize,
          pageModel: {
            pageNo,
            pageSize
          }
        },
        (sorter && sorter.field && { sortField: sorter.field }) || {},
        (sorter && sorter.order && { sortOrder: sorter.order }) || {},
        { ...filters }
      );
      const result = this.data(parameter);
      // 对接自己的通用数据接口需要修改下方代码中的 r.pageNo, r.recordCount, r.rows
      // eslint-disable-next-line
      if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
        result.then(respData => {
            if (Array.isArray(respData)) {
              this.hasRowNo && (respData.forEach((x,i)=>x['rowNo'] = i + 1));
              this.localDataSource = respData;
              return;
            }
            if (respData && respData.rows && respData.rows.length >= 0) {
              this.localPagination =
                (this.showPagination &&
                  Object.assign({}, this.localPagination, {
                    current: respData.pageNo, // 返回结果中的当前分页数
                    total: respData.recordCount, // 返回结果中的总记录数
                    showSizeChanger: this.showSizeChanger,
                    pageSize: (pagination && pagination.pageSize) || this.localPagination.pageSize,
                    size: 'large',
                  })) ||
                false;
              // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
              if (respData.rows.length === 0 && this.showPagination && this.localPagination.current > 1) {
                this.localPagination.current--;
                this.loadData(null,null,null);
                return;
              }

              this.hasRowNo && respData.rows.forEach((x,i)=>x['rowNo'] = (this.localPagination.current - 1) * this.localPagination.pageSize + i + 1);

              // 这里用于判断接口是否有返回 r.recordCount 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 recordCount 小于等于 pageNo * pageSize 的大小
              // 当情况满足时，表示数据不满足分页大小，关闭 table 分页功能
              try {
                if (
                  ['auto', true].includes(this.showPagination) &&
                  respData.recordCount <= respData.pageNo * this.localPagination.pageSize
                ) {
                  this.localPagination.hideOnSinglePage = false; // 单页时是否隐藏分页工具条 。这里设置始终不隐藏
                }
              } catch (e) {
                this.showPagination = false;
              }
              this.localDataSource = respData.rows; // 返回结果中的数组数据
            } else {
              this.localDataSource = [];
            }
          })
          .finally(() => {
            this.localLoading = false;
          });
      }
    },
  },
  render() {
    const props = {};
    const localKeys = Object.keys(this.$data);

    localKeys.forEach(k => {
      const key = k.substring(5, 6).toLowerCase().concat(k.substring(6));
      props[key] = this[k];
    });

    const rowClassName = (_record, index) => (index % 2 === 1 ? 'table-striped' : null);
    const table = h(
      Table,
      {
        ...this.$attrs,
        ...this.$props,
        ...props,
        class:this.class?this.class:['ant-table-striped'],
        rowClassName,
        columns: this.columns,
        onChange: this.loadData,
        onExpand: (expanded, record) => {
          this.$emit('expand', expanded, record);
        },
      },
      this.$slots
    );

    return h('div', { className: 'table-wrapper' }, [table]);
  },
};
</script>

<style scoped>
.ant-table-striped :deep(.table-striped) td {
  background-color: #fafafa;
}
</style>
